using System;
using System.Collections.Generic;
using System.Text;
using FireStarter.Base;
using FireStarter.CodeGeneration;
using FireStarter.CodeGeneration.Generator;
using FireStarterModeller.BO;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.BO.Loaders;
using Habanero.Util;
using NUnit.Framework;

namespace FireStarter.Test.CodeGeneration.Generator
{
    [TestFixture]
    public class TestValueDelegatesDictionary
    {
        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            BORegistry.DataAccessor = new DataAccessorInMemory();
            ClassDef.ClassDefs.Add(new XmlClassDefsLoader(BOBroker.GetClassDefsXml(), new DtdLoader()).LoadClassDefs());
        }

        private static ValueDelegate GetValueDelegate(string delegateName)
        {
            ValueDelegatesDictionary valueDelegatesDictionary = new ValueDelegatesDictionary();
            return valueDelegatesDictionary[delegateName];
        }

        [Test]
        public void TestDefaultDelegatesAvailable()
        {
            //---------------Set up test pack-------------------

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            ValueDelegatesDictionary valueDelegatesDictionary = new ValueDelegatesDictionary();
            //---------------Test Result -----------------------
            Assert.AreEqual(6, valueDelegatesDictionary.Count);
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey("Class_HasCompulsoryProperties"));
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey("Property_HasDefaultValue"));
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey("Property_IsClassID"));
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey("Property_IsNonIDPrimaryKey"));
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey("Property_IsInKey"));
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey("ValidValue"));
        }

        [Test]
        public void Test_CaseInsensitive()
        {
            //---------------Set up test pack-------------------
            ValueDelegatesDictionary valueDelegatesDictionary = new ValueDelegatesDictionary();
            const string propertyName = "Abc1";
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            valueDelegatesDictionary.Add(propertyName, delegate { return null; });
            //---------------Test Result -----------------------
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey(propertyName));
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey(propertyName.ToUpper()));
            Assert.IsTrue(valueDelegatesDictionary.ContainsKey(propertyName.ToLower()));
            Assert.IsNotNull(valueDelegatesDictionary[propertyName]);
            Assert.IsNotNull(valueDelegatesDictionary[propertyName.ToUpper()]);
            Assert.IsNotNull(valueDelegatesDictionary[propertyName.ToLower()]);
        }

        [Test]
        public void Test_Class_HasCompulsoryProperties_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "Property1");
            ((DMProperty) modelProperty).Compulsory = true;
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Class_HasCompulsoryProperties")(dmClass);
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof (bool), result);
            Assert.IsTrue((bool) result);
        }

        [Test]
        public void Test_Class_HasCompulsoryProperties_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "Property1");
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Class_HasCompulsoryProperties")(dmClass);
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof (bool), result);
            Assert.IsFalse((bool) result);
        }

        [Test]
        public void Test_Class_HasCompulsoryProperties_ThrowsExceptionIfNotModelClass()
        {
            //---------------Set up test pack-------------------
            ModelPropertyStub modelPropertyStub = new ModelPropertyStub("TestProperty");
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Class_HasCompulsoryProperties")(modelPropertyStub);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("when the context is not a type of IModelClass", ex.Message);
            }
        }

        [Test]
        public void Test_Property_HasDefaultValue_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePKPropertyOnClass((DMClass) dmClass, "TestClassID");
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_HasDefaultValue")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse((bool) result);
        }

        [Test]
        public void Test_Property_HasDefaultValue_ReturnsTrueIFHasDefault()
        {
            //---------------Set up test pack-------------------
            ModelPropertyStub modelPropertyStub = new ModelPropertyStub("TestProperty");
            modelPropertyStub.DefaultValue = TestUtilsCodeGen.GetRandomString();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_HasDefaultValue")(modelPropertyStub);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool) result);
        }

        [Test]
        public void Test_Property_HasDefaultValue_ReturnsTrueIFIsID()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            ((DMClass) dmClass).ObjectIdentity = new DMObjectIdentity();
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            ((DMClass) dmClass).ObjectIdentity.Properties.Add((DMProperty) modelProperty);
            ((DMClass) dmClass).ObjectIdentity.IsObjectID = true;

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_HasDefaultValue")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool) result);
        }

        [Test]
        public void Test_Property_HasDefaultValue_ThrowsExceptionIfNotModelProperty()
        {
            //---------------Set up test pack-------------------
            ValueDelegatesDictionary valueDelegatesDictionary = new ValueDelegatesDictionary();
            ValueDelegate valueDelegate = valueDelegatesDictionary["Property_HasDefaultValue"];

            ModelSolutionStub modelSolutionStub = new ModelSolutionStub();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_HasDefaultValue")(modelSolutionStub);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("when the context is not a type of I", ex.Message);
            }
        }

        [Test]
        public void Test_Property_HasDefaultValue_ThrowsExceptionIfNoParentSet()
        {
            //---------------Set up test pack-------------------
            IModelProperty modelProperty = new DMProperty();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_HasDefaultValue")(modelProperty);
                Assert.Fail("Expected to throw an EXCEPTION");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("does not have a parent, or the parent is not a class", ex.Message);
            }
        }

        [Test]
        public void Test_Property_HasDefaultValue_ReturnsTrueIFIsIDOfSuperClass()
        {
            //---------------Set up test pack-------------------
            IModelClass superClass = TestUtilsCodeGen.CreateModelClass("SuperClass");
            ((DMClass) superClass).ObjectIdentity = new DMObjectIdentity();
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) superClass, "TestClassID");
            ((DMClass)superClass).ObjectIdentity.Properties.Add((DMProperty) modelProperty);
            ((DMClass)superClass).ObjectIdentity.IsObjectID = true;
            
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            DMInheritanceRelationship dmInheritanceRelationship = new DMInheritanceRelationship();
            ((DMClass)dmClass).InheritanceSuperClassRelationship = dmInheritanceRelationship;
            dmInheritanceRelationship.SuperClass = (DMClass) superClass;

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_HasDefaultValue")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool)result);
        }

        [Test]
        public void Test_Property_IsClassID_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = new DMObjectIdentity();
            ((DMClass)dmClass).ObjectIdentity.Properties.Add((DMProperty) modelProperty);
            ((DMClass)dmClass).ObjectIdentity.IsObjectID = true;
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsClassID")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool)result);
        }

        [Test]
        public void Test_Property_IsClassID_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass)dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = new DMObjectIdentity();
            ((DMClass)dmClass).ObjectIdentity.Properties.Add((DMProperty)modelProperty);
            ((DMClass)dmClass).ObjectIdentity.IsObjectID = false;
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsClassID")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse((bool)result);
        }

        [Test]
        public void Test_Property_IsClassID_WhenNoPK_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass)dmClass, "TestClassID");
            ((DMClass) dmClass).ObjectIdentity = null;
            
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsClassID")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse((bool)result);
        }

        [Test]
        public void Test_Property_IsClassID_ThrowsExceptionIfNotModelProperty()
        {
            //---------------Set up test pack-------------------
            ModelSolutionStub modelSolutionStub = new ModelSolutionStub();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_IsClassID")(modelSolutionStub);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("when the context is not a type of IModelProperty", ex.Message);
            }
        }

        [Test]
        public void Test_Property_IsClassID_ThrowsExceptionIfNoParentSet()
        {
            //---------------Set up test pack-------------------
            IModelProperty modelProperty = new DMProperty();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_IsClassID")(modelProperty);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("does not have a parent, or the parent is not a class", ex.Message);
            }
        }

        [Test]
        public void Test_Property_IsNonIDPrimaryKey_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = new DMObjectIdentity();
            ((DMClass)dmClass).ObjectIdentity.Properties.Add((DMProperty)modelProperty);
            ((DMClass)dmClass).ObjectIdentity.IsObjectID = false;
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsNonIDPrimaryKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool)result);
        }

        [Test]
        public void Test_Property_IsNonIDPrimaryKey_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = new DMObjectIdentity();
            ((DMClass)dmClass).ObjectIdentity.Properties.Add((DMProperty)modelProperty);
            ((DMClass)dmClass).ObjectIdentity.IsObjectID = true;
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsNonIDPrimaryKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse((bool)result);
        }

        [Test]
        public void Test_Property_IsNonIDPrimaryKey_WhenNoPK_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass)dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = null;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsNonIDPrimaryKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse((bool)result);
        }

        [Test]
        public void Test_Property_IsNonIDPrimaryKey_ThrowsExceptionIfNotModelProperty()
        {
            //---------------Set up test pack-------------------
            ModelSolutionStub modelSolutionStub = new ModelSolutionStub();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_IsNonIDPrimaryKey")(modelSolutionStub);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("when the context is not a type of IModelProperty", ex.Message);
            }
        }

        [Test]
        public void Test_Property_IsNonIDPrimaryKey_ThrowsExceptionIfNoParentSet()
        {
            //---------------Set up test pack-------------------
            IModelProperty modelProperty = new DMProperty();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_IsNonIDPrimaryKey")(modelProperty);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("does not have a parent, or the parent is not a class", ex.Message);
            }
        }

        [Test]
        public void Test_Property_IsInKey_ReturnsTrue_InPrimaryKey()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = new DMObjectIdentity();
            ((DMClass)dmClass).ObjectIdentity.Properties.Add((DMProperty)modelProperty);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsInKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool)result);
        }

        [Test]
        public void Test_Property_IsInKey_ReturnsTrue_InAlternateKey()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass)dmClass, "TestClassID");

            IModelKey modelKey = new DMUniqueConstraint();
            modelKey.KeyProperties.Add(modelProperty);
            DMUniqueConstraintProperty dmUniqueConstraintProperty = new DMUniqueConstraintProperty();
            dmUniqueConstraintProperty.Property = (DMProperty)modelProperty;
            ((DMUniqueConstraint)modelKey).UniqueConstraintProperties.Add(dmUniqueConstraintProperty);
            ((DMClass)dmClass).ObjectIdentity = new DMObjectIdentity();
            ((DMClass)dmClass).UniqueConstraints.Add((DMUniqueConstraint)modelKey);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsInKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool)result);
        }

        [Test]
        public void Test_Property_IsInKey_WhenNoPK_ButInAlternateKey_ReturnsTrue()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass)dmClass, "TestClassID");

            IModelKey modelKey = new DMUniqueConstraint();
            modelKey.KeyProperties.Add(modelProperty);
            DMUniqueConstraintProperty dmUniqueConstraintProperty = new DMUniqueConstraintProperty();
            dmUniqueConstraintProperty.Property = (DMProperty)modelProperty;
            ((DMUniqueConstraint)modelKey).UniqueConstraintProperties.Add(dmUniqueConstraintProperty);
            ((DMClass)dmClass).ObjectIdentity = null;
            ((DMClass)dmClass).UniqueConstraints.Add((DMUniqueConstraint)modelKey);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsInKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsTrue((bool)result);
        }

        [Test]
        public void Test_Property_IsInKey_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = new DMObjectIdentity();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsInKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse((bool)result);
        }

        [Test]
        public void Test_Property_IsInKey_WhenNoPK_ReturnsFalse()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass)dmClass, "TestClassID");
            ((DMClass)dmClass).ObjectIdentity = null;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            object result = GetValueDelegate("Property_IsInKey")(modelProperty);
            //---------------Test Result -----------------------
            Assert.IsFalse((bool)result);
        }

        [Test]
        public void Test_Property_IsInKey_ThrowsExceptionIfNotModelProperty()
        {
            //---------------Set up test pack-------------------
            ModelSolutionStub modelSolutionStub = new ModelSolutionStub();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_IsInKey")(modelSolutionStub);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("when the context is not a type of IModelProperty", ex.Message);
            }
        }

        [Test]
        public void Test_Property_IsInKey_ThrowsExceptionIfNoParentSet()
        {
            //---------------Set up test pack-------------------
            IModelProperty modelProperty = new DMProperty();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("Property_IsInKey")(modelProperty);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("does not have a parent, or the parent is not a class", ex.Message);
            }
        }

        [Test]
        public void Test_ValidValue_NoType()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("ValidValue")(modelProperty);
            //---------------Test Result -----------------------
            Assert.AreEqual("null", result);
        }

        [Test]
        public void Test_ValidValue_String()
        {
            //---------------Set up test pack-------------------
            IModelClass dmClass = TestUtilsCodeGen.CreateModelClass("TestClass");
            IModelProperty modelProperty = TestUtilsCodeGen.CreatePropertyOnClass((DMClass) dmClass, "TestClassID");
            TestUtilsCodeGen.SetPropertyType((DMProperty)modelProperty, "System", "String");
            string upper = modelProperty.Parent.ToString();
            string _className = StringUtilities.ToLowerFirstLetter(upper) + "1";
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            object result = GetValueDelegate("ValidValue")(modelProperty);
            //---------------Test Result -----------------------
            Assert.AreEqual("factory.GetValidPropValue(" + _className + "=>" + _className + "." + modelProperty.PropertyName + ")", result);
        }

        [Test]
        public void Test_ValidValue_ThrowsExceptionIfNotModelProperty()
        {
            //---------------Set up test pack-------------------
            ModelSolutionStub modelSolutionStub = new ModelSolutionStub();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            try
            {
                object result = GetValueDelegate("ValidValue")(modelSolutionStub);
                Assert.Fail("Expected to throw an GenerationException");
            }
                //---------------Test Result -----------------------
            catch (GenerationException ex)
            {
                StringAssert.Contains("when the context is not a type of IModelProperty", ex.Message);
            }
        }
    }
}
